home *** CD-ROM | disk | FTP | other *** search
/ PD Collection CD 1 / PD Collection CD 1.iso / textual / pdimpres / !PD-Impres / c / pd-dff next >
Text File  |  1990-08-25  |  14KB  |  356 lines

  1. /* -> c.pd-dff */
  2.  
  3. /*
  4.  * Program to convert PipeDream files into text files suitable for Impression, while still retaining style and formatting
  5.  * information where possible.
  6.  * ie This program converts PipeDream files into DDF format
  7.  *
  8.  * © Stuart Hickinbottom 27mar90
  9.  */
  10.  
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <limits.h>
  14. #include <signal.h>
  15.  
  16. /* Macro definitions */
  17. #define Special_character '%'   /* The special character that indicates a command                                         */
  18. #define Max_highlight_size 12   /* The maximum length of a PipeDream highlight code, I think this is column definition    */
  19. #define BOOL int                /* Define a 'type' BOOL                                                                   */
  20. #define TRUE 1                  /* Define the value of TRUE                                                               */
  21. #define FALSE 0                 /* Define the value of FALSE                                                              */
  22. #define Buffer_increase 256     /* Define the amount by which the buffer is incremented. Should be >= max DDF line length */
  23.  
  24. #define My_name "pd-dff"
  25. #define Brief_help "convert PipeDream files into DDF files"
  26. #define Version_number "1.01"
  27. #define Version_date "Mar 27 1990"
  28. #define My_credits "© Stuart Hickinbottom 1990"
  29.  
  30. /* Global variables */
  31. static char in_file_name[255];         /* Filespec of PipeDream file to convert      */
  32. static char *in_file = in_file_name;   /* Define a pointer to this name              */
  33. static char out_file_name[255];        /* Filespec of DDF format output file         */
  34. static char *out_file = out_file_name; /* Define a pointer to this name              */
  35. static char *pd_text = NULL;           /* Pointer to loaded PipeDream text in memory */
  36. static char *ddf_text = NULL;          /* Pointer to DDF format converted text       */
  37. static int  ddf_size;                  /* The size of the DDF text buffer. Increases */
  38. static int  offset_ddf = 0;            /* The offset into the DDF text buffer        */
  39. static int  offset_pd = 0;             /* The offset into the PD text buffer         */
  40. static BOOL verbose   = FALSE;         /* Flag to indicate verbose operation         */
  41.  
  42. /*
  43.  * This table defines the translation from PipeDream highlight codes to Impression DDF commands. For each highlight code
  44.  * there is the PipeDream command name and then the Impression style name. There is then a flag which this code uses to
  45.  * remember whether the style is currently on or off. This table may be freely expanded.
  46.  */
  47.  
  48. static char *highlight_trans[][] =
  49.             {
  50.             {"H1", "Underline",     "Off"}, /* Style:   Underline         */
  51.             {"H2", "Bold",          "Off"}, /* Style:   Bold              */
  52.             {"H3", "Main Heading",  "Off"}, /* Style:   Extended sequence */
  53.             {"H4", "Italic",        "Off"}, /* Style:   Italic            */
  54.             {"H5", "Subscript",     "Off"}, /* Style:   Subscript         */
  55.             {"H6", "Superscript",   "Off"}, /* Style:   Superscript       */
  56.             {"H7", "Typewriter",    "Off"}, /* Style:   Alternative font  */
  57.             {"H8", "Sub-heading",   "Off"}, /* Style:   User defined      */
  58.             {"JL", "Fully Justify", "Off"}, /* Style:   Justified         */
  59.             {"JR", "Fully Justify", "Off"}, /* Style:   Justified         */
  60.             {"C",  "Centre",        "Off"}, /* Justify: Centre            */
  61.             {"**", "",              ""   }  /* Terminating value          */
  62.             };
  63.  
  64. static char *highlight_ignore[] = /* Define highlight codes which cause the 'interpreter' to skip the line */
  65.             {
  66.             "OP",                 /* Ignore page description lines   */
  67.             "**",                 /* Terminating value               */
  68.             };
  69.  
  70. /* Table of special highlights which are converted directly into text, for example the percentage symbol */
  71. static char *highlight_text[][] =
  72.             {
  73.             {"PC", "%"      },        /* Convert PC into the percentage symbol */
  74.             {"**", ""       }         /* Terminating value                     */
  75.             };
  76.  
  77. /* Any highlight code which is not in any of the above tables is simply skipped over - no action is taken */
  78.  
  79. int main(int argc, char *argv[])
  80. {
  81.  void convert_pd_file(int), write_ddf_file(void), clean_up(void), give_help(void), describe_function(void), handle_escape(int);
  82.  int read_pd_file(void), pd_file_size, arg_num, strcpy(char *, char *), last_flag;
  83.  char *arg;
  84.  
  85.  signal(SIGINT, handle_escape);
  86.  last_flag = 0;
  87.  for (arg_num = 1; arg_num < argc; ++arg_num)
  88.   {
  89.   arg = argv[arg_num];
  90.   if (arg[0] == '-')
  91.    {
  92.    last_flag = arg_num;
  93.    if (arg[1] == 'd' || arg[1] == 'D')
  94.     describe_function();
  95.    else
  96.     if (arg[1] == 'h' || arg[1] == 'H') give_help();
  97.    else
  98.     if (arg[1] == 'v' || arg[1] == 'V') verbose = TRUE;
  99.    else
  100.     {
  101.     fprintf(stderr, "%s: unknown flag '%s', try '-help'\n", My_name, arg);
  102.     exit(EXIT_SUCCESS);
  103.     }
  104.    }
  105.   }
  106.  if ((argc - last_flag) < 3)
  107.   {
  108.   fprintf(stderr, "%s: (Fatal) bad args - use '-help' if in need of help\n", My_name);
  109.   exit(EXIT_FAILURE);
  110.   }
  111.  strcpy(in_file_name, argv[last_flag+1]);
  112.  strcpy(out_file_name, argv[last_flag+2]);
  113.  pd_file_size = read_pd_file();
  114.  convert_pd_file(pd_file_size);
  115.  write_ddf_file();
  116.  clean_up();
  117.  if (verbose) fprintf(stderr, "%s: conversion complete\n", My_name);
  118. }
  119.  
  120. /* Give help on syntax */
  121. void give_help(void)
  122. {
  123.  fprintf(stderr, "\n%s vsn %s [%s] - %s\n\n", My_name, Version_number, Version_date, Brief_help);
  124.  fprintf(stderr, "%s [options] infile outfile\n\n",My_name);
  125.  fprintf(stderr, "Options:-\n");
  126.  fprintf(stderr, "-describe  describe what the program does\n");
  127.  fprintf(stderr, "-help      give help on syntax\n");
  128.  fprintf(stderr, "-verbose   give information on progress\n\n");
  129.  fprintf(stderr, "Example:-\n      %s pipe_file ddf_file\n\n%s\n", My_name, My_credits);
  130.  exit(EXIT_SUCCESS);
  131. }
  132.  
  133. /* Describe the programs method of operation */
  134. void describe_function(void)
  135. {
  136.  int highlight_number = 0;
  137.  int strcmp(char *, char *);
  138.  fprintf(stderr, "\n\
  139. %s translates a PipeDream document into a DDF (document description\n\
  140. format) file which is suitable for inclusion in packages such as Computer\n\
  141. Concepts' Impression. Highlight codes are converted into the corresponding DDF\n\
  142. style names (eg. hightlight 1 is 'Bold'), and incompatable highlights are\n\
  143. ignored (eg. the definition of a heading or footer is skipped over). Styles are\n\
  144. always turned off at the end of lines (as is the case in PipeDream).\n\
  145. Note: because of the way in which PipeDream formats text, paragraphs will\n\
  146. have to be editied to remove the carriage-returns at the end of each line.\n\
  147. There is no way that this could be performed automatically, reliably.\n\
  148. Currently, the following highlight conversions are performed:\n\n", My_name);
  149.  while (strcmp(highlight_trans[highlight_number][0], "**") != 0)
  150.   {
  151.   fprintf(stderr, "%6s ... %s\n", highlight_trans[highlight_number][0], highlight_trans[highlight_number][1]);
  152.   highlight_number++;
  153.   }
  154.  fprintf(stderr, "\n");
  155.  exit(EXIT_SUCCESS);
  156. }
  157.  
  158. /* Read in the PipeDream file, allocating enough space to hold the entire file in one go */
  159. int read_pd_file(void)
  160. {
  161.  FILE *pd_file_handle;
  162.  int pd_file_size;
  163.  char *malloc(long);
  164.  void clean_up(void);
  165.  
  166.  if (verbose) fprintf(stderr, "%s: opening file '%s'", My_name, in_file);
  167.  if ((pd_file_handle = fopen(in_file, "r")) == NULL)
  168.   {
  169.   if (verbose) fprintf(stderr, "\n");
  170.   fprintf(stderr, "%s: (Fatal) file '%s' could not be opened (not found?)\n", My_name, in_file);
  171.   exit(EXIT_FAILURE);
  172.   }
  173.  fseek(pd_file_handle, 0,2);
  174.  pd_file_size = (int)ftell(pd_file_handle);
  175.  fseek(pd_file_handle, 0,0);
  176.  if (verbose) fprintf(stderr, ", file size is %d bytes\n", pd_file_size);
  177.  if ((pd_text = malloc(pd_file_size)) == NULL)
  178.   {
  179.   fprintf(stderr, "%s: (Fatal) insufficient memory to load '%s'\n", My_name, in_file);
  180.   if (verbose) fprintf(stderr, "%s: closing file '%s'\n", My_name, in_file);
  181.   fclose(pd_file_handle);
  182.   clean_up();
  183.   exit(EXIT_FAILURE);
  184.   }
  185.  if (verbose) fprintf(stderr, "%s: reading text from file '%s'\n", My_name, in_file);
  186.  fread(pd_text, 1, pd_file_size, pd_file_handle);
  187.  if (verbose) fprintf(stderr, "%s: closing file '%s'\n", My_name, in_file);
  188.  fclose(pd_file_handle);
  189.  return(pd_file_size);
  190. }
  191.  
  192. /* Write out the DDF format version of the text to a file */
  193. void write_ddf_file(void)
  194. {
  195.  FILE *ddf_file_handle;
  196.  void clean_up(void);
  197.  int chars_written;
  198.  
  199.  if (verbose) fprintf(stderr, "%s: opening file '%s'\n", My_name, out_file);
  200.  if ((ddf_file_handle = fopen(out_file, "w")) == NULL)
  201.   {
  202.   fprintf(stderr, "%s: (Fatal) file '%s' could not be opened (disc full?)\n", My_name, out_file);
  203.   clean_up();
  204.   exit(EXIT_FAILURE);
  205.   }
  206.  if (verbose) fprintf(stderr, "%s: writing to file '%s'\n", My_name, out_file);
  207.  chars_written = fwrite(ddf_text, 1, offset_ddf, ddf_file_handle);
  208.  if (chars_written != offset_ddf)
  209.   {
  210.   fprintf(stderr, "%s: (Fatal) write error, %d bytes written (disc full/corrupted?)\n", My_name, chars_written);
  211.   clean_up();
  212.   exit(EXIT_FAILURE);
  213.   }
  214.  if (verbose) fprintf(stderr, "%s: closing file '%s'\n", My_name, out_file);
  215.  fclose(ddf_file_handle);
  216. }
  217.  
  218. /* Clean up at the end of the conversion, or if an error has occured - ie free memory etc. */
  219. void clean_up(void)
  220. {
  221.  free(pd_text);
  222.  free(ddf_text);
  223. }
  224.  
  225. /* Convert the PipeDream file into a DDF format file - this is the biggie!! */
  226. void convert_pd_file(int pd_file_size)
  227. {
  228.  void handle_embedded(void), all_highlights_off(void), ensure_highlights_off(void), increase_buffer(char *), clean_up(void);
  229.  char *malloc(int);
  230.  if (verbose) fprintf(stderr, "%s: converting text\n", My_name);
  231.  ddf_size = 0;
  232.  increase_buffer(NULL);
  233.  ddf_text = malloc(Buffer_increase);
  234.  if (ddf_text == NULL)
  235.   {
  236.   fprintf(stderr, "%s: (Fatal) unable to allocate store for DDF text\n", My_name);
  237.   clean_up();
  238.   exit(EXIT_FAILURE);
  239.   }
  240.  all_highlights_off();
  241.  while (offset_pd < pd_file_size)
  242.   {
  243.   while (pd_text[offset_pd] == Special_character) handle_embedded(); /* Handle highlight */
  244.   if ((pd_text[offset_pd] == '\x0a') || (pd_text[offset_pd] == '\x0d')) ensure_highlights_off();
  245.   if (offset_pd < pd_file_size) ddf_text[offset_ddf++] = pd_text[offset_pd];
  246.   offset_pd++;
  247.   if ((ddf_size - offset_ddf) < Buffer_increase) /* If the DDF text buffer needs to be increased... */
  248.    {
  249.    increase_buffer(ddf_text);
  250.    }
  251.   }
  252. }
  253.  
  254. /* Handle an embedded command, converting it into DDF */
  255. void handle_embedded(void)
  256. {
  257.  char character, *highlight, *malloc(int);
  258.  int highlight_size, highlight_number, strcmp(char *, char *);
  259.  void toggle_highlight_on(int), insert_ddf(int);
  260.  highlight = malloc(Max_highlight_size);
  261.  highlight_size = 0;
  262.  while ((character = pd_text[++offset_pd]) != Special_character) highlight[highlight_size++] = character; /* Read command */
  263.  offset_pd++;
  264.  highlight[highlight_size] = NULL;
  265.  highlight_number = 0;
  266.  while ((strcmp(highlight_ignore[highlight_number], "**") != 0) && strcmp(highlight_ignore[highlight_number], highlight) != 0)
  267.   highlight_number++; /* Check if this command is to be ignored */
  268.  if (strcmp(highlight_ignore[highlight_number], "**") != 0) /* If this command should be ignored then... */
  269.   while ((pd_text[offset_pd] != '\x0a') && (pd_text[offset_pd++] != '\x0d')); /* Skip the rest of this line */
  270.  else
  271.   {
  272.   highlight_number = 0;
  273.   while ((strcmp(highlight_trans[highlight_number][0], "**") != 0) && strcmp(highlight_trans[highlight_number][0], highlight) != 0)
  274.    highlight_number++; /* Check if this command is to be translated to a DDF command */
  275.   if (strcmp(highlight_trans[highlight_number][0], "**") != 0) /* If this command should be translated then... */
  276.    {
  277.    toggle_highlight_on(highlight_number);
  278.    insert_ddf(highlight_number);
  279.    }
  280.   else
  281.    {
  282.    highlight_number = 0;
  283.    while ((strcmp(highlight_text[highlight_number][0], "**") != 0) && strcmp(highlight_text[highlight_number][0], highlight) != 0)
  284.     highlight_number++; /* Check if this command is to be translated to a text alternative */
  285.    if (strcmp(highlight_text[highlight_number][0], "**") != 0) /* If this command should be translated then... */
  286.     offset_ddf += sprintf(ddf_text+offset_ddf, "%s", highlight_text[highlight_number][1]); /* Copy in the translated string */
  287.    }
  288.   }
  289.  free(highlight);
  290. }
  291.  
  292. /* Increase the buffer for the DDF text by the amount defined by Buffer_increase */
  293. void increase_buffer(char *ddf_text)
  294. {
  295.  void clean_up(void);
  296.  ddf_text = realloc(ddf_text, Buffer_increase);
  297.  if (ddf_text == NULL)
  298.   {
  299.   fprintf(stderr, "%s: (Fatal) unable to allocate store to DDF text buffer\n", My_name);
  300.   clean_up();
  301.   exit(EXIT_FAILURE);
  302.   }
  303.  ddf_size += Buffer_increase;
  304. }
  305.  
  306. /* Toggle my flag which indicates whether a highlight is currently turn on. Used to turn all off at end of a line */
  307. void toggle_highlight_on(int highlight_number)
  308. {
  309.  if (highlight_trans[highlight_number][2] == "Off")
  310.   highlight_trans[highlight_number][2] = "On";
  311.  else
  312.   highlight_trans[highlight_number][2] = "Off";
  313. }
  314.  
  315. /* This inserts the DDF equivalent of the highlight code, using the 'on flag' to decide whether to turn it on or off */
  316. void insert_ddf(int highlight_number)
  317. {
  318.  offset_ddf += sprintf(ddf_text+offset_ddf, "{\"%s\" %s}", highlight_trans[highlight_number][1], highlight_trans[highlight_number][2]);
  319. }
  320.  
  321. /* Reset all the highlights to be initially off */
  322. void all_highlights_off(void)
  323. {
  324.  int highlight_number, strcmp(char *, char *);
  325.  highlight_number = 0;
  326.  while (strcmp(highlight_trans[highlight_number][0], "**") != 0)
  327.   highlight_trans[highlight_number++][2] = "Off";
  328. }
  329.  
  330. /* Ensure that all highlights are off at the end of a line, by issuing 'off' DDF commands to turn highlights off */
  331. void ensure_highlights_off(void)
  332. {
  333.  int highlight_number, strcmp(char*, char*);
  334.  void toggle_highlight_on(int), insert_ddf(int);
  335.  highlight_number = 0;
  336.  while (strcmp(highlight_trans[highlight_number][0], "**") != 0)
  337.   {
  338.   if (highlight_trans[highlight_number][2] == "On")
  339.    {
  340.    toggle_highlight_on(highlight_number);
  341.    insert_ddf(highlight_number);
  342.    }
  343.   highlight_number++;
  344.   }
  345. }
  346.  
  347. /* Called when escape signal received */
  348. void handle_escape(int signo)
  349. {
  350.   void clean_up(void);
  351.   fprintf(stderr, "%s: interrupt received from user - conversion aborted\n", My_name);
  352.   signal(signo, handle_escape);
  353.   clean_up();
  354.   exit(EXIT_FAILURE);
  355. }
  356.